/*************************************************************************/
/** Copyright.															**/
/** FileName: TextPaintPanel.cpp										**/
/** Author: Polarix														**/
/** Description: Used for paint and preview pixelated text.				**/
/*************************************************************************/
//=======================================================================//
//= Include files.													    =//
//=======================================================================//
#include "TextPaintCtrl.h"
#include "Settings.h"
#include "Debug.h"
#include "Utility.h"

//=======================================================================//
//= Function define.										            =//
//=======================================================================//
TextPaintCtrl::TextPaintCtrl(wxWindow *pclsParent, wxWindowID iWinID, const wxSize& clsSizeInPixel, const wxColor& clsInitializeFillColor):
wxLCDBase(pclsParent, iWinID, wxDefaultPosition, clsSizeInPixel, wxT("Text Paint Coltrol"))
{
	m_clsPixelLColour = clsInitializeFillColor;
	m_clsPixelHColour = (*wxWHITE);
	SetPixelUnitSize(ConfigurationInstance().PanelConfiguration().PixelUnitSize());
	SetBorderWidth(0);
	SetGridVisibled(true);
	SetGridColor(wxColour(127, 127, 127));
	FillColour(m_clsPixelLColour);
}

TextPaintCtrl::~TextPaintCtrl(void)
{

}

void TextPaintCtrl::SetPanelColour(const wxColour& clsPanelColour, bool bRefreshNow)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(clsPanelColour != m_clsPixelLColour)
	{
		// Replace old panel color.
		ReplaceColour(m_clsPixelLColour, clsPanelColour);
		DBG_LOG("Replace panel color from #%06X to #%06X.", CSS_LIKE_COLOR(m_clsPixelLColour), CSS_LIKE_COLOR(clsPanelColour));
		// Set new panel color.
		m_clsPixelLColour = clsPanelColour;
		// Refresh display.
		if(true == bRefreshNow)
		{
			RefreshDisplay();
		}
	}
}

void TextPaintCtrl::SetPixelColour(const wxColour& clsPixelColour, bool bRefreshNow)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(clsPixelColour != m_clsPixelHColour)
	{
		// Replace old pixel color.
		ReplaceColour(m_clsPixelHColour, clsPixelColour);
		DBG_LOG("Replace pixel color from #%06X to #%06X.", CSS_LIKE_COLOR(m_clsPixelHColour), CSS_LIKE_COLOR(clsPixelColour));
		// Set new pixel color.
		m_clsPixelHColour = clsPixelColour;
		// Refresh display.
		if(true == bRefreshNow)
		{
			RefreshDisplay();
		}
	}
}

void TextPaintCtrl::SetFont(const FontSettings& clsFont)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	m_clsTextConv.SetFont(clsFont);
}

int TextPaintCtrl::GetPixel(const int iPosX, const int iPosY)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	int				iReturn;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(WX_LCD_PIX_RGB(GetPixelUnitColor(iPosX, iPosY)) == WX_LCD_PIX_RGB(m_clsPixelHColour.GetRGBA()))
	{
		iReturn = 1;
	}
	else
	{
		iReturn = 0;
	}

	return iReturn;
}

void TextPaintCtrl::SetPixel(const int iPosX, const int iPosY, const int iValue)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(1 == iValue)
	{
		SetPixelUnitColor(iPosX, iPosY, m_clsPixelHColour);
	}
	else
	{
		SetPixelUnitColor(iPosX, iPosY, m_clsPixelLColour);
	}
}

void TextPaintCtrl::CleanScreen(void)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	FillColour(m_clsPixelLColour);
}

void TextPaintCtrl::PaintChar(int iPixelX, int iPixelY, const CharacterRasterizer& clsDCObject)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	int						iHorizontalPixelNumber;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	GetPixelNumber(&iHorizontalPixelNumber, NULL);

	if((iPixelX < iHorizontalPixelNumber) && (clsDCObject.GetWidth() > 0) && (clsDCObject.GetHeight() > 0))
	{
		for(int iY=0; iY<clsDCObject.GetHeight(); iY++)
		{
			for(int iX=0; iX<clsDCObject.GetWidth(); iX++)
			{
				if(1 == clsDCObject.GetPixel(iX, iY))
				{
					SetPixelUnitColor(iPixelX+iX, iPixelY+iY, m_clsPixelHColour);
				}
				else
				{
					SetPixelUnitColor(iPixelX+iX, iPixelY+iY, m_clsPixelLColour);
				}
			}
		}
	}
}

void TextPaintCtrl::AutoHorizontalPixelNumber(void)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	int						iWidth;
	int						iPixelWidth;
	int						iHorizontalPixelNumber;

	/*----------------------------------*/
	/* Initialize						*/
	/*----------------------------------*/
	iWidth =				GetSize().GetWidth();
	iPixelWidth =			GetPixelUnitSize().GetWidth();

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	iHorizontalPixelNumber = iWidth/iPixelWidth+1;
	SetHorizontalPixelNumber(iHorizontalPixelNumber);
}

void TextPaintCtrl::AutoVerticalPixelNumber(void)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	int						iHeight;
	int						iPixelHeight;
	int						iVerticalPixelNumber;

	/*----------------------------------*/
	/* Initialize						*/
	/*----------------------------------*/
	iHeight =				GetSize().GetHeight();
	iPixelHeight =			GetPixelUnitSize().GetHeight();

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	iVerticalPixelNumber = iHeight/iPixelHeight;
	SetVerticalPixelNumber(iVerticalPixelNumber);
}

void TextPaintCtrl::PaintText(const wxString& cstrText)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	int						iPaintPosX = 0;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	/* Clean up paint panel. */
	CleanScreen();
	/* Paint string if not empty. */
	if(cstrText.Length() > 0)
	{
		wxString::const_iterator clsIterator = cstrText.begin();
		while((clsIterator != cstrText.end()) && (iPaintPosX < wxLCDBase::GetHorizontalPixelNumber()))
		{
			if(false == wxIscntrl(*clsIterator))
			{
				/* Convert text to image. */
				m_clsTextConv.Convert(*clsIterator);
				/* Paint text. */
				PaintChar(iPaintPosX, 0, m_clsTextConv);
				iPaintPosX += m_clsTextConv.GetWidth();
			}
			clsIterator++;
		}
	}
	/* Update paint text content.  */
	m_strText = cstrText;
}
